#include <shell/simple_shell.h>


namespace shell
{


simple_shell::simple_shell(shell::baud_rate rate)
  : _return(0)
  , _argc(1)
  , _pos(0)
{
  Serial.begin(rate);
  _argv[0] = _buffer;

  while (Serial.read() != -1);

  auto list = [this](void)
  {
    _functions.print_words();
    return 0;
  };

  _functions.insert("list", utils::function<int(void)>(list));

  prompt();
}


void simple_shell::update(void)
{
  int val = Serial.read();

  while (val != -1)
  {
    switch (char(val))
    {
      case '\n':
      case '\r':
      {
        Serial.println();

        _buffer[_pos] = '\0';
        --_argc;

        if (_pos)
        {
          command* f = _functions[_argv[0]];
          if (f)
          {
            _return = (*f)(_argc, _argv+1);
          }
          else
          {
            Serial.print('"');
            Serial.print(_argv[0]);
            Serial.println("\" is not defined !");
            _return = -1;
          }
        }
        prompt();

        _pos = 0;
        _argc = 1;
        break;
      }

      case ' ':
      {
        if (!_pos) break;

        _buffer[_pos] = '\0';
        ++_pos;

        _argv[_argc] = _buffer + _pos;
        ++_argc;

        Serial.print(' ');

        break;
      }
      default:
      {
        _buffer[_pos] = char(val);
        Serial.print(char(val));
        ++_pos;
      }
    }

    val = Serial.read();
  }
}


void simple_shell::prompt(void)
{
  Serial.print("atmsh [");
  Serial.print(_return);
  Serial.print("] ~ ");
}


} // shell
